package com.zq.solution;

/**
 * @ClassName MatrixScore
 * @Description
 * 861. 翻转矩阵后的得分
 *   有一个二维矩阵A 其中每个元素的值为0或1。
 *   移动是指选择任一行或列，并转换该行或列中的每一个值：将所有 0 都更改为 1，将所有 1 都更改为 0。
 *   在做出任意次数的移动后，将该矩阵的每一行都按照二进制数来解释，矩阵的得分就是这些数字的总和。
 *   返回尽可能高的分数。
 * 示例：
 *   输入：[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
 *   输出：39
 * 解释：
 *   转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
 *   0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
 * 提示：
 *   1 <= A.length <= 20
 *   1 <= A[0].length <= 20
 *   A[i][j]是0 或1
 * @Author ZQ
 * @Date 2020/12/7 9:27
 * @Version 1.0
 */
public class MatrixScore {
    public static int matrixScore(int[][] A) {
        int colLength = A[0].length,rowLength = A.length;
        /*第一列的0全部转换为1*/
        for (int i = 0; i < rowLength; i++){
            if (A[i][0] == 0) {
                for (int j = 0; j < colLength; j++){
                    A[i][j] = Math.abs(A[i][j] - 1);
                }
            }
        }
        /*从第二列开始统计0和1的总数，如果0比1多，则将此列转换*/
        for (int j = 1; j < colLength; j++){
            int countOne = 0,countZero = 0;
            for (int[] row : A) {
                if (row[j] == 0) countZero++;
                else countOne++;
            }
            if (countZero > countOne){
                for (int[] nums : A)
                    nums[j] = 1 - nums[j];
            }
        }
        /* 计算结果*/
        int result = 0;
        for (int[] row : A) {
            int sum = 0;
            for (int j = 0; j < colLength; j++) {
                if (row[j] == 1)
                    sum += Math.pow(2, colLength - 1 - j);
            }
            result += sum;
        }
        return result;
    }
    /*官方的解法，fxxk...*/
    public int matrixScore1(int[][] A) {
        int m = A.length, n = A[0].length;
        int ret = m * (1 << (n - 1));

        for (int j = 1; j < n; j++) {
            int nOnes = 0;
            for (int[] row : A) {
                if (row[0] == 1) {
                    nOnes += row[j];
                } else {
                    nOnes += (1 - row[j]); // 如果这一行进行了行反转，则该元素的实际取值为 1 - A[i][j]
                }
            }
            int k = Math.max(nOnes, m - nOnes);
            ret += k * (1 << (n - j - 1));
        }
        return ret;
    }

    public static void main(String[] args) {
        int[][] A = new int[][]{{0},{1},{1}};
        System.out.println(matrixScore(A));
    }
}
